package com.agriculture.monitor.filter;

import com.agriculture.monitor.base.ResultInfo;
import com.agriculture.monitor.base.TContext;
import com.agriculture.monitor.constant.Constant;
import com.agriculture.monitor.entity.User;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


@WebFilter(urlPatterns = "/*", filterName = "userTokenFilter")
public class UserTokenFilter implements Filter {

    private static Logger LOG = LoggerFactory.getLogger(UserTokenFilter.class);
    // 接口白名单
    String[] whiteList = new String[]{"login", "logout", "register", "sms", "token", "swagger-ui.html", "version", "api", "favicon.ico"};

    private static final String AUTHORIZATION = "Authorization";


    @Override
    public void init(FilterConfig filterConfig)
            throws ServletException {
        LOG.info("init UserTokenFilter");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException,
            ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("content-type", "application/json;charset=UTF-8");
        String requestURI = request.getRequestURI();

        for (String string : whiteList) {
            if (requestURI.contains(string)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }
        String token = request.getHeader(AUTHORIZATION);
        if (StringUtils.isBlank(token)) {
            String jsonString = JSON.toJSONString(new ResultInfo<>(ResultInfo.UNAUTHORIZED, "请检查Token"));
            PrintWriter out = response.getWriter();
            out.print(jsonString);
            return;
        }
        try {
            String userInfo = Jwts.parser().setSigningKey(Constant.JWT_SECRET).parseClaimsJws(token).getBody().getSubject();
            TContext.set(JSONObject.parseObject(userInfo, User.class));
        } catch (MalformedJwtException e) {
            String jsonString = JSON.toJSONString(new ResultInfo<>(ResultInfo.UNAUTHORIZED, "Token不合法"));
            PrintWriter out = response.getWriter();
            out.print(jsonString);
            return;
        } catch (ExpiredJwtException e) {
            overdueLogin(response);
            return;
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    public void overdueLogin(HttpServletResponse response) throws IOException {
        String jsonString = JSON.toJSONString(new ResultInfo<>(ResultInfo.UNAUTHORIZED, "Token已过期，请重新登录"));
        PrintWriter out = response.getWriter();
        out.print(jsonString);
    }

    @Override
    public void destroy() {
        LOG.info("UserTokenFilter has destroyed.");
    }
}